package cn.harry.modular.system.service.impl;

import cn.harry.common.constant.CacheConstants;
import cn.harry.config.property.CaptchaProperties;
import cn.harry.modular.system.enums.CaptchaTypeEnums;
import cn.harry.modular.system.service.SysCaptchaService;
import cn.harry.modular.system.vo.CaptchaResult;
import cn.hutool.captcha.AbstractCaptcha;
import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.generator.CodeGenerator;
import cn.hutool.core.util.IdUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.awt.*;
import java.util.concurrent.TimeUnit;

/**
 * 图片验证码
 *
 * @author harry
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class SysCaptchaServiceImpl implements SysCaptchaService {

    private final RedisTemplate<String, Object> redisTemplate;

    private final CaptchaProperties captchaProperties;
    private final CodeGenerator codeGenerator;
    private final Font captchaFont;

    @Override
    public boolean validate(String uuid, String code) {
        // 从redis中获取验证码
        String redisCode = (String) redisTemplate.opsForValue().get(CacheConstants.CAPTCHA_CODE + uuid);
        if (redisCode == null) {
            return false;
        } else {
            boolean redisCodeVerify = codeGenerator.verify(redisCode, code);
            // 验证完成后删除redis中的验证码
            redisTemplate.delete(CacheConstants.CAPTCHA_CODE + uuid);
            return redisCodeVerify;
        }
    }

    @Override
    public CaptchaResult getCaptcha() {

        String captchaType = captchaProperties.getType();
        int width = captchaProperties.getWidth();
        AbstractCaptcha captcha = getAbstractCaptcha(captchaType, width);

        captcha.setGenerator(codeGenerator);
        captcha.setTextAlpha(captchaProperties.getTextAlpha());
        captcha.setFont(captchaFont);

        String code = captcha.getCode();
        String imageBase64Data = captcha.getImageBase64Data();

        // 验证码文本缓存至Redis，用于登录校验
        String uuid = IdUtil.fastSimpleUUID();
        // 设置验证码过期时间
        Long expireSeconds = captchaProperties.getExpireSeconds();
        redisTemplate.opsForValue().set(CacheConstants.CAPTCHA_CODE + uuid, code, expireSeconds, TimeUnit.SECONDS);

        return CaptchaResult.builder().img(imageBase64Data).uuid(uuid).build();
    }

    private AbstractCaptcha getAbstractCaptcha(String captchaType, int width) {
        int height = captchaProperties.getHeight();
        int interfereCount = captchaProperties.getInterfereCount();
        int codeLength = captchaProperties.getCode().getLength();

        AbstractCaptcha captcha;
        if (CaptchaTypeEnums.CIRCLE.name().equalsIgnoreCase(captchaType)) {
            captcha = CaptchaUtil.createCircleCaptcha(width, height, codeLength, interfereCount);
        } else if (CaptchaTypeEnums.GIF.name().equalsIgnoreCase(captchaType)) {
            captcha = CaptchaUtil.createGifCaptcha(width, height, codeLength);
        } else if (CaptchaTypeEnums.LINE.name().equalsIgnoreCase(captchaType)) {
            captcha = CaptchaUtil.createLineCaptcha(width, height, codeLength, interfereCount);
        } else if (CaptchaTypeEnums.SHEAR.name().equalsIgnoreCase(captchaType)) {
            captcha = CaptchaUtil.createShearCaptcha(width, height, codeLength, interfereCount);
        } else {
            throw new IllegalArgumentException("Invalid captcha type: " + captchaType);
        }
        return captcha;
    }
}